/*
 * Copyright:  2018 smarabbit studio.
 *
 *  Licensed under the Confluent Community License; you may not use this file
 *  except in compliance with the License.  You may obtain a copy of the License at
 *
 *  http://www.confluent.io/confluent-community-license
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OF ANY KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations under the License.
 *
 *  @作   者： 黄开晖 (117227773@qq.com)
 *  @日   期:  2020年9月4日
 */
package com.massyframework.beanskin.runtime.service;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;

/**
 * {@link AllowAccessPredicateFactory} 提供判断是否允许装配件域访问服务的断言
 */
abstract class AllowAccessPredicateFactory {

    private static final Predicate<String> ALLALLOW = new EveryBodyAllow();

    /**
     * 创造{@link Predicate}
     * @param domains {@link String}数组，可以为null.
     * @return {@link Predicate}
     */
    public static Predicate<String> createAllowAccess(String[] domains){
        if (domains == null) return ALLALLOW;
        if (domains.length == 0) return ALLALLOW;

        return new LimitGroupIdAllow(domains);
    }

    private static class LimitGroupIdAllow implements Predicate<String> {

        private Set<String> allowSet;

        public LimitGroupIdAllow(String[] domains){
            this.allowSet = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(domains)));
        }

        /**
         * Evaluates this predicate on the given argument.
         *
         * @param s the input argument
         * @return {@code true} if the input argument matches the predicate,
         * otherwise {@code false}
         */
        @Override
        public boolean test(String s) {
            return this.allowSet.contains(s);
        }
    }

    /**
     * 任意装配域都允许
     */
    private static class EveryBodyAllow implements Predicate<String> {

        /**
         * Evaluates this predicate on the given argument.
         *
         * @param s the input argument
         * @return {@code true} if the input argument matches the predicate,
         * otherwise {@code false}
         */
        @Override
        public boolean test(String s) {
            return true;
        }
    }
}

